<template>
  <div
    class="pin-container"
    :class="{ dragging: isDragging }"
    @dblclick="handleDoubleClick"
    @mousedown.stop.prevent="handleMouseDown"
    @contextmenu.prevent
    @mousemove="handleMouseMove"
    @mouseup="handleMouseUp"
    @mouseleave="handleMouseUp"
    tabindex="0"
    ref="containerRef"
  >
    <img
      v-if="imageUrl"
      :src="imageUrl"
      alt="pinned image"
      class="pinned-image"
      draggable="false"
      @load="onImageLoad"
      @error="onImageError"
    />
    <div v-else class="loading">加载中...</div>

    <!-- 加载状态遮罩 -->
    <div v-if="!isImageLoaded && imageUrl" class="loading-mask">
      <div class="loading-spinner"></div>
    </div>

    <!-- 调试信息面板 -->
    <div v-if="showDebug" class="debug-panel">
      <div class="debug-header">
        <span>调试信息</span>
        <div class="debug-header-buttons">
          <button @click="copyDebugInfo" class="debug-btn" title="复制日志">
            📋
          </button>
          <button @click="showDebug = false" class="debug-close">×</button>
        </div>
      </div>
      <div class="debug-content">
        <div></div>
        <div v-for="log in debugList" :key="log">
          {{ log }}
        </div>
      </div>
    </div>

    <!-- 调试按钮 -->
    <button
      v-if="isDebug"
      @click.stop="showDebug = true"
      @mousedown.stop
      class="debug-toggle"
    >
      调试
    </button>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick } from "vue";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { LogicalPosition } from "@tauri-apps/api/dpi";
import { invoke, convertFileSrc } from "@tauri-apps/api/core";
import { useRoute } from "vue-router";

const route = useRoute();
const imageUrl = ref("");
const appWindow = getCurrentWebviewWindow();
const showDebug = ref(false);
const containerRef = ref<HTMLElement | null>(null);
const isDebug = ref(false);

// 加载状态
const isImageLoaded = ref(false);

// 长按拖动相关状态
const isLongPressing = ref(false);
const isDragging = ref(false);
const longPressTimer = ref<number | null>(null);
const dragStartX = ref(0);
const dragStartY = ref(0);
const windowStartX = ref(0);
const windowStartY = ref(0);
const currentMouseX = ref(0); // 实时追踪当前鼠标位置
const currentMouseY = ref(0);
const LONG_PRESS_DURATION = 100; // 长按时间阈值（毫秒）

// 拖动性能优化：使用 requestAnimationFrame
let rafId: number | null = null;
let pendingX: number | null = null;
let pendingY: number | null = null;
let isUpdatingPosition = false;

// 鼠标位置追踪监听器
let trackMousePositionListener: ((e: MouseEvent) => void) | null = null;

// 调试信息

const debugList = ref<string[]>([]);
// 更新调试信息
const updateDebugInfo = (title: string, message: string) => {
  if (isDebug.value) {
    debugList.value.push(`${title}: ${message}`);
  }
};

// 复制调试信息
const copyDebugInfo = async () => {
  const info = debugList.value.join("\n");

  try {
    await navigator.clipboard.writeText(info);
    alert("调试信息已复制到剪贴板！");
  } catch (error) {
    console.error("复制失败:", error);
    // 备用方案：创建一个临时文本框
    const textarea = document.createElement("textarea");
    textarea.value = info;
    textarea.style.position = "fixed";
    textarea.style.opacity = "0";
    document.body.appendChild(textarea);
    textarea.select();
    try {
      document.execCommand("copy");
      alert("调试信息已复制到剪贴板！");
    } catch (e) {
      alert("复制失败，请手动复制日志");
    }
    document.body.removeChild(textarea);
  }
};

// 图片加载成功
const onImageLoad = () => {
  updateDebugInfo("图片加载成功", "✅ 图片加载成功");
  isImageLoaded.value = true;
};

// 图片加载失败
const onImageError = (e: Event) => {
  updateDebugInfo("图片加载失败", `❌ 图片加载失败: ${e.type || "未知错误"}`);
};

// 加载图片的函数
const loadImage = async (path: string) => {
  try {
    // 使用 invoke 读取文件并转换为 base64 data URL（最可靠的方法）
    const dataUrl = await invoke<string>("read_file_as_base64", {
      filePath: path,
    });

    imageUrl.value = dataUrl;

    // 验证图片是否能加载
    const img = new Image();
    img.onload = async () => {
      updateDebugInfo("图片加载成功", "✅ 图片加载成功");
      isImageLoaded.value = true;
      // 获取圆角配置
      try {
        const config = await invoke<{ border_radius: number }>(
          "get_screenshot_config"
        );
        if (containerRef.value) {
          containerRef.value.style.borderRadius = `${config.border_radius}px`;
          // 同时设置图片的圆角，稍微减小一点以适应边框
          const imgElement = containerRef.value.querySelector("img");
          if (imgElement) {
            imgElement.style.borderRadius = `${Math.max(
              0,
              config.border_radius - 2
            )}px`;
          }
        }
      } catch (e) {
        console.error("Failed to load screenshot config:", e);
      }
    };
    img.onerror = (e) => {
      updateDebugInfo(
        "图片加载失败",
        `❌ 图片加载失败: ${e instanceof Event ? e.type : "未知错误"}`
      );
    };
    img.src = dataUrl;
  } catch (e) {
    const errorMsg = e instanceof Error ? e.message : String(e);
    updateDebugInfo("读取文件失败", `❌ 读取文件失败: ${errorMsg}`);

    // 如果 invoke 失败，尝试使用 convertFileSrc 作为备用方案
    try {
      const convertedSrc = convertFileSrc(path);
      imageUrl.value = convertedSrc;
      updateDebugInfo(
        "使用 convertFileSrc 备用方案...",
        convertedSrc.substring(0, 100) + "..."
      );
    } catch (fallbackError) {
      // 备用方案也失败
    }
  }
};

onMounted(async () => {
  // 等待 router 准备好
  await new Promise((resolve) => setTimeout(resolve, 100));

  // 从 URL query 获取 path（base64 编码）
  let path: string | null = null;

  // 从 vue-router 的 query 获取
  if (route.query.path) {
    path = route.query.path as string;
  } else {
  }

  // 如果 query 还没准备好，尝试从 window.location 解析
  if (!path) {
    try {
      const hash = window.location.hash;
      const queryIndex = hash.indexOf("?");

      if (queryIndex !== -1) {
        const queryString = hash.substring(queryIndex + 1);
        const params = new URLSearchParams(queryString);
        path = params.get("path");
      }
    } catch (e) {
      // 解析 URL 失败
    }
  }

  if (path) {
    try {
      // 先尝试 URL 解码（浏览器可能自动解码了一次）
      let pathToDecode = path;
      try {
        pathToDecode = decodeURIComponent(path);
      } catch (urlDecodeError) {
        // URL 解码失败，使用原始路径
      }

      // Base64 解码
      const decodedPath = atob(pathToDecode);

      loadImage(decodedPath);
    } catch (e) {
      // 如果 base64 解码失败，尝试直接使用（可能是普通 URL 编码）
      loadImage(path);
    }
  } else {
  }

  // 监听键盘事件

  // 使用 capture 模式确保能捕获到事件
  window.addEventListener("keydown", handleKeyDown, true);

  // 确保窗口获得焦点
  try {
    await appWindow.setFocus();
  } catch (e) {
    // 设置焦点失败
  }

  // 延迟一下再设置焦点，确保窗口完全加载
  setTimeout(async () => {
    try {
      await appWindow.setFocus();

      // 设置容器元素的焦点，确保能接收键盘事件
      if (containerRef.value) {
        containerRef.value.focus();
      }
    } catch (e) {
      // 延迟设置焦点失败
    }
  }, 200);

  // 使用 nextTick 确保 DOM 已渲染
  await nextTick();
  if (containerRef.value) {
    containerRef.value.focus();
  }
});

onUnmounted(() => {
  window.removeEventListener("keydown", handleKeyDown, true);
  // 清理长按计时器
  if (longPressTimer.value !== null) {
    clearTimeout(longPressTimer.value);
  }
  // 取消待处理的动画帧
  if (rafId !== null) {
    cancelAnimationFrame(rafId);
    rafId = null;
  }
  // 清理全局事件监听器
  document.removeEventListener("mousemove", handleGlobalMouseMove);
  document.removeEventListener("mouseup", handleGlobalMouseUp);
});

// 处理键盘事件
const handleKeyDown = async (event: KeyboardEvent) => {
  // 检查是否是 Esc 键
  if (
    event.key === "Escape" ||
    event.key === "Esc" ||
    event.keyCode === 27 ||
    event.code === "Escape"
  ) {
    event.preventDefault();
    event.stopPropagation();
    await handleClose();
  }
};

const handleClose = async () => {
  try {
    // 使用 Rust 命令关闭窗口（避免权限问题）
    await invoke("close_current_window");
  } catch (e) {}
};

// 使用 requestAnimationFrame 优化窗口位置更新
const updateWindowPosition = async () => {
  if (pendingX === null || pendingY === null || isUpdatingPosition) {
    return;
  }

  isUpdatingPosition = true;
  const x = Math.round(pendingX);
  const y = Math.round(pendingY);
  pendingX = null;
  pendingY = null;

  try {
    // 直接使用窗口 API，避免 invoke 的 IPC 开销
    await appWindow.setPosition(new LogicalPosition(x, y));
  } catch (error) {
    // 静默失败
  } finally {
    isUpdatingPosition = false;

    // 如果还有待更新的位置，继续更新
    if (pendingX !== null && pendingY !== null) {
      rafId = requestAnimationFrame(updateWindowPosition);
    } else {
      rafId = null;
    }
  }
};

// 全局鼠标移动处理函数（用于拖动时）
const handleGlobalMouseMove = (e: MouseEvent) => {
  if (!isDragging.value) {
    return;
  }

  // 计算鼠标移动距离（使用屏幕坐标的变化，避免窗口移动导致的相对坐标抖动）
  const deltaX = e.screenX - dragStartX.value;
  const deltaY = e.screenY - dragStartY.value;

  // 计算新窗口位置（窗口初始位置 + 鼠标移动距离）
  const newX = windowStartX.value + deltaX;
  const newY = windowStartY.value + deltaY;

  updateDebugInfo("拖动中", `screen:(${e.screenX}, ${e.screenY})`);

  // 保存待更新的位置
  pendingX = newX;
  pendingY = newY;

  // 使用 requestAnimationFrame 来优化更新频率
  if (rafId === null) {
    rafId = requestAnimationFrame(updateWindowPosition);
  }
};

// 全局鼠标释放处理函数（用于拖动时）
const handleGlobalMouseUp = async () => {
  // 取消待处理的动画帧
  if (rafId !== null) {
    cancelAnimationFrame(rafId);
    rafId = null;
  }

  // 确保最终位置被更新
  if (pendingX !== null && pendingY !== null) {
    try {
      await appWindow.setPosition(new LogicalPosition(pendingX, pendingY));
      windowStartX.value = pendingX;
      windowStartY.value = pendingY;
    } catch (error) {
      // 静默失败
    }
    pendingX = null;
    pendingY = null;
  }

  // 移除全局事件监听器
  document.removeEventListener("mousemove", handleGlobalMouseMove);
  document.removeEventListener("mouseup", handleGlobalMouseUp);

  // 结束拖动
  isLongPressing.value = false;
  isDragging.value = false;
  isUpdatingPosition = false;
  updateDebugInfo("就绪", "就绪");
};

// 处理鼠标按下事件（开始长按检测）
const handleMouseDown = async (e: MouseEvent) => {
  // 忽略调试面板和按钮的点击
  if (
    (e.target as HTMLElement).closest(".debug-panel") ||
    (e.target as HTMLElement).closest(".debug-toggle") ||
    (e.target as HTMLElement).closest(".debug-close")
  ) {
    return;
  }

  // 记录初始鼠标位置（使用屏幕坐标）
  currentMouseX.value = e.screenX;
  currentMouseY.value = e.screenY;
  updateDebugInfo("等待长按...", `screen:(${e.screenX}, ${e.screenY})`);

  // 在按住期间持续追踪鼠标位置（这样长按触发时能用最新位置）
  trackMousePositionListener = (e: MouseEvent) => {
    currentMouseX.value = e.screenX;
    currentMouseY.value = e.screenY;
  };
  document.addEventListener("mousemove", trackMousePositionListener);

  // 获取窗口当前位置（统一转换为逻辑坐标，避免高分屏下坐标跳动）
  try {
    const factor = await appWindow.scaleFactor();
    const position = await appWindow.outerPosition();
    windowStartX.value = position.x / factor;
    windowStartY.value = position.y / factor;
    updateDebugInfo(
      "窗口位置",
      `${windowStartX.value}, ${windowStartY.value} (逻辑)`
    );
  } catch (error) {
    // 如果获取失败，使用默认值
    try {
      // position() 返回的通常是 PhysicalPosition，也需要转换
      // 保险起见，假设 outerPosition 是首选，如果失败了直接使用默认值
      windowStartX.value = 0;
      windowStartY.value = 0;
    } catch (e2) {
      windowStartX.value = 0;
      windowStartY.value = 0;
    }
  }

  // 开始长按计时器
  isLongPressing.value = false;
  longPressTimer.value = window.setTimeout(async () => {
    // 移除位置追踪监听器
    trackMousePositionListener &&
      document.removeEventListener("mousemove", trackMousePositionListener);
    trackMousePositionListener = null;

    // 【关键】重新获取窗口位置（转换为逻辑坐标）
    try {
      const factor = await appWindow.scaleFactor();
      const currentPos = await appWindow.outerPosition();
      windowStartX.value = currentPos.x / factor;
      windowStartY.value = currentPos.y / factor;
    } catch (error) {
      // 静默失败，使用之前的值
    }

    // 【关键】使用实时追踪的当前鼠标位置作为拖动起点
    dragStartX.value = currentMouseX.value;
    dragStartY.value = currentMouseY.value;

    // 设置拖动状态
    isLongPressing.value = true;
    isDragging.value = true;
    updateDebugInfo(
      "拖动中",
      `窗口位置: (${windowStartX.value}, ${windowStartY.value})`
    );
    updateDebugInfo(
      "拖动中",
      `鼠标位置: (${dragStartX.value}, ${dragStartY.value})`
    );

    // 添加拖动事件监听器
    document.addEventListener("mousemove", handleGlobalMouseMove);
    document.addEventListener("mouseup", handleGlobalMouseUp);
  }, LONG_PRESS_DURATION);
};

// 处理鼠标移动事件（拖动窗口）
const handleMouseMove = (e: MouseEvent) => {
  if (!isDragging.value) {
    return;
  }
  handleGlobalMouseMove(e);
};

// 处理鼠标释放事件（结束拖动）
const handleMouseUp = () => {
  // 清除长按计时器
  if (longPressTimer.value !== null) {
    clearTimeout(longPressTimer.value);
    longPressTimer.value = null;
  }

  // 移除鼠标位置追踪监听器（如果还在等待长按期间就释放了）
  trackMousePositionListener &&
    document.removeEventListener("mousemove", trackMousePositionListener);
  trackMousePositionListener = null;

  // 如果正在拖动，移除全局事件监听器并结束拖动
  if (isDragging.value) {
    document.removeEventListener("mousemove", handleGlobalMouseMove);
    document.removeEventListener("mouseup", handleGlobalMouseUp);

    // 结束拖动
    isLongPressing.value = false;
    isDragging.value = false;
    updateDebugInfo("就绪", "就绪");
  }
};

// 处理双击事件（关闭窗口）
const handleDoubleClick = () => {
  handleClose();
};
</script>

<style scoped>
.pin-container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0;
  outline: none; /* 移除焦点时的轮廓 */
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
  /* 添加边框和阴影 */
  border: 1px solid rgba(10, 132, 255, 0.2);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.1);
  border-radius: 4px;
}

.pin-container:focus {
  outline: none; /* 确保焦点时不显示轮廓 */
}

.pin-container.dragging {
  cursor: move;
  border-color: rgba(10, 132, 255, 0.9);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4), 0 0 0 2px rgba(10, 132, 255, 0.5);
}

.pinned-image {
  width: 100%;
  height: 100%;
  object-fit: fill;
  user-select: none;
  display: block;
  pointer-events: none; /* 防止图片干扰拖动 */
  border-radius: 2px;
}

.loading {
  color: white;
  background: rgba(0, 0, 0, 0.5);
  padding: 10px;
  border-radius: 4px;
}

.debug-panel {
  position: fixed;
  top: 10px;
  right: 10px;
  background: rgba(0, 0, 0, 0.9);
  color: #0f0;
  padding: 15px;
  border-radius: 8px;
  font-family: "Courier New", monospace;
  font-size: 12px;
  max-width: 500px;
  max-height: 80vh;
  overflow-y: auto;
  z-index: 10000;
  border: 2px solid #0f0;
  box-shadow: 0 4px 12px rgba(0, 255, 0, 0.3);
  pointer-events: auto;
}

.debug-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid #0f0;
  font-weight: bold;
}

.debug-header-buttons {
  display: flex;
  gap: 8px;
  align-items: center;
}

.debug-btn,
.debug-close {
  background: transparent;
  border: 1px solid #0f0;
  color: #0f0;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.debug-close {
  font-size: 18px;
}

.debug-btn:hover,
.debug-close:hover {
  background: rgba(0, 255, 0, 0.2);
}

.debug-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.debug-content div {
  word-break: break-all;
  line-height: 1.4;
}

.debug-content strong {
  color: #0ff;
  margin-right: 8px;
}

.debug-toggle {
  position: fixed;
  top: 10px;
  right: 10px;
  background: rgba(0, 0, 0, 0.7);
  color: #0f0;
  border: 1px solid #0f0;
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  z-index: 9999;
  pointer-events: auto;
}

.debug-toggle:hover {
  background: rgba(0, 255, 0, 0.2);
}

.loading-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}

.loading-spinner {
  width: 30px;
  height: 30px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: #fff;
  animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
